<template>
  <el-dialog
      v-model="dialogVisible"
      :title="'卫星编号【'+ selectedSatelliteCodes +'】指令【' + instructionCode+' '+ instructionName + ' ' + instructionFlag +'】参数设置'"
      width="90%"
      top="5vh"
      :before-close="handleClose"
  >
    <el-alert
        title="注意：只能修改参数的默认值，其他字段为只读。修改的值必须符合参数长度和类型要求。"
        type="warning"
        show-icon
        style="margin-bottom: 15px;"
    />

    <el-table
        :data="parameterList"
        border
        stripe
        style="width: 100%"
        max-height="60vh"
    >
      <el-table-column
          prop="parameterSequence"
          label="参数顺序"
          width="80"
      />
      <el-table-column
          prop="parameterCode"
          label="参数代号"
          width="120"
      />
      <el-table-column
          prop="parameterName"
          label="参数名称"
          width="200"
      />
      <el-table-column
          prop="parameterLength"
          label="参数长度"
          width="80"
      />
      <el-table-column
          prop="parameterType"
          label="参数类型"
          width="120"
      >
        <template #default="scope">
          <el-tag :type="getTagType(scope.row.parameterType)">
            {{ scope.row.parameterType }}
          </el-tag>
        </template>
      </el-table-column>
      <el-table-column
          prop="processManner"
          label="处理方式"
          width="100"
      />

<!--
      <el-table-column
          prop="parameterDefinition"
          label="参数定义"
          width="150"
      />
      -->
      <el-table-column
        prop="parameterDefinition"
        label="参数定义"
        width="150"
        show-overflow-tooltip
        :show-tooltip-when-overflow="true"
    />
      <el-table-column
          prop="defaultValueView"
          label="默认值"
          width="150"
      />
      <el-table-column prop="defaultValue" label="参数设置" width="240">
        <template #default="scope">

          <!-- 下拉情况：字典 + 固定值 + 有定义 -->
          <el-select
              v-if="
        scope.row.parameterType === '字典' &&
        scope.row.processManner === '固定值' &&
        scope.row.parameterDefinition
      "
              v-model="scope.row.defaultValue"
              placeholder="请选择"
              clearable
          >
            <el-option
                v-for="opt in parseDictOptions(scope.row.parameterDefinition)"
                :key="opt.key"
                :label="opt.label"
                :value="opt.key"
            />
          </el-select>

          <!-- 原输入框：其他情况 -->
          <el-tooltip
              :disabled="Number(scope.row.parameterLength) !== 0"
              content="参数长度为 0，不可输入"
              placement="top"
          >

            <el-input
                v-model="scope.row.defaultValue"
                :placeholder="
          Number(scope.row.parameterLength) === 0
            ? '无需填写'
            : '请输入' + scope.row.parameterLength + '位值'
        "
                :maxlength="Number(scope.row.parameterLength) || undefined"
                :minlength="Number(scope.row.parameterLength) || undefined"
                @blur="validateValue(scope.row)"
            />
<!--            <el-input
                v-model="scope.row.defaultValue"
                :disabled="Number(scope.row.parameterLength) === 0 ||
                                  scope.row.processManner === '固定值'"
                :placeholder="
          Number(scope.row.parameterLength) === 0
            ? '无需填写'
            : '请输入' + scope.row.parameterLength + '位值'
        "
                :maxlength="Number(scope.row.parameterLength) || undefined"
                :minlength="Number(scope.row.parameterLength) || undefined"
                @blur="validateValue(scope.row)"
            />-->
          </el-tooltip>
        </template>
      </el-table-column>

      <el-table-column
          prop="unit"
          label="单位"
          width="80"
      />
      <el-table-column
          prop="dimension"
          label="量纲"
          width="60"
      />
      <el-table-column
          prop="parameterDesc"
          label="参数说明"
          min-width="160"
          show-overflow-tooltip
      />
    </el-table>

    <template #footer>
      <span class="dialog-footer">
        <el-button @click="handleClose">取消</el-button>
        <el-button type="primary" @click="saveParameters">保存</el-button>
        <!-- 新增：另存为 -->
        <el-button type="success" @click="openSaveAsDialog">另存为</el-button>
      </span>
    </template>
  </el-dialog>


  <!-- 2. 另存为弹窗 -->
  <el-dialog
      v-model="saveAsVisible"
      title="另存为新指令"
      width="480px"
      append-to-body
  >
    <el-form
        ref="saveAsFormRef"
        :model="saveAsForm"
        :rules="saveAsRules"
        label-width="90"
    >
      <el-form-item label="卫星编号">
        <el-tag
            v-for="code in props.selectedSatelliteCodes"
            :key="code"
            style="margin-right:4px"
        >
          {{ code }}
        </el-tag>
      </el-form-item>

      <el-form-item label="指令代码" prop="instructionCode">
        <el-input
            v-model.trim="saveAsForm.instructionCode"
            placeholder="请输入指令代码"
            clearable
            @input="debounceCheck"
        />
      </el-form-item>
      <el-form-item label="指令标识" prop="instructionFlag">
        <el-input
            v-model.trim="saveAsForm.instructionFlag"
            placeholder="请输入指令标识"
            clearable
            @input="debounceCheck"
        />
      </el-form-item>
      <el-form-item label="指令名称" prop="instructionName">
        <el-input
            v-model.trim="saveAsForm.instructionName"
            placeholder="请输入指令名称"
            clearable
            @input="debounceCheck"
        />
      </el-form-item>
      <el-form-item label="备注" prop="comment">
        <el-input
            v-model.trim="saveAsForm.comment"
            placeholder="请输入指令名称"
            clearable
        />
      </el-form-item>

      <el-form-item>
        <span v-if="uniqueLoading">校验中...</span>
        <span v-else :style="{color: isUnique ? '#67C23A' : '#F56C6C'}">
        {{ uniqueMsg }}
      </span>
      </el-form-item>
    </el-form>

    <template #footer>
      <el-button @click="saveAsVisible=false">取消</el-button>
      <el-button
          type="primary"
          :disabled="!isUnique || uniqueLoading"
          @click="confirmSaveAs"
      >
        确认保存
      </el-button>
    </template>
  </el-dialog>
</template>


<script setup>
import { ref, watch } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'

import {
  getInstructionParametersSerive, InstructTypesSerive,
  saveInstructionParametersSerive,
} from "@/api/satellite/SingleInstructionSending.js"

import axios from 'axios'                 // 若依已封装，可换成 request
import { debounce } from 'lodash-es'
import {debounceCheckSerive, confirmSaveAsSerive} from "@/api/satellite/zhilingguanli.js";

// 导入store
import store from '@/store'
// 获取当前用户信息
const userId = store.state.value.user.id
const userName = store.state.value.user.name
const nickName = store.state.value.user.nickName

// 定义props
const props = defineProps({
  visible: {
    type: Boolean,
    default: false
  },
  selectedSatelliteCodes1: {
    type: String,
    default: ''
  },
  selectedSatelliteCodes: {
    type: Array,
    default: () => []
  },
  zhunBeiFaSongZhiLingId: {
    type: String,
    default: ''
  },
  instructionCode: {
    type: String,
    default: ''
  },
  instructionName: {
    type: String,
    default: ''
  },
  satelliteIds:  {
    type: Array,
    default: () => []
  },

  satelliteId: {
    type: String,
    default: ''
  }
})

// 定义emit事件
const emit = defineEmits(['update:visible', 'saved'])

// 对话框显示状态
const dialogVisible = ref(false)

// 参数列表
const parameterList = ref([])

// 指令标识
const instructionFlag = ref('')

// 监听visible变化
watch(() => props.visible, (newVal) => {
  dialogVisible.value = newVal
  if (newVal) {
    fetchParameters()
  }
})

// 监听对话框状态变化
watch(dialogVisible, (newVal) => {
  emit('update:visible', newVal)
})

// 获取参数类型对应的标签样式
const getTagType = (type) => {
  const typeMap = {
    '字典类型': 'success',
    '固定值': '',
    '无符号类型': 'info',
    '有符号类型': 'info',
    '公式': 'warning',
    '布尔值': 'danger',
    '16进制': 'warning',
    '时间戳': '',
    '日期': '',
    '文本': '',
    '双精度浮点数': 'info'
  }
  return typeMap[type] || ''
}

// 从后端获取参数列表
const fetchParameters = async () => {

    const param = {
      instructionCode: props.instructionCode,
      satelliteId: props.satelliteId,
      instructionName: props.instructionName,
      selectedSatelliteCodes: props.selectedSatelliteCodes,
      zhunBeiFaSongZhiLingId: props.zhunBeiFaSongZhiLingId,
      satelliteIds: props.satelliteIds,
    }


  // 这里调用API获取参数列表
    await getInstructionParametersSerive(param).then((response) => {
      console.log(response)
      if (response.code === 200) {
        parameterList.value = response.data
        // 设置 指令标识
        instructionFlag.value = parameterList.value[0].instructionFlag


      } else {
        ElMessage.error('获取参数列表失败: ' + response.data.message)
      }
    }).catch((error) => {
      ElMessage.error('获取参数列表失败: ' + error.message)
    })
}

const parseDictOptions = (def) => {
  if (!def) return [];
  return def
      .split(';')
      .filter(Boolean)
      .map(seg => {
        const [key, label] = seg.split(':');
        return {
          key:   key.trim(),
          label: `${key.trim()}:${label.trim()}`   // 0:关闭
        };
      });
};
// 验证输入值
const validateValue = (row) => {
  const value0 = String(row.defaultValue).trim();
  const type = row.parameterType;
  const def = row.parameterDefinition || '';

  // 如果长度为 0，直接跳过所有校验
  if (Number(row.parameterLength) === 0) return true

  let value = row.defaultValue
  console.log('验证输入值:',row.defaultValue)
  const length = row.parameterLength
  // '参数定义';
  const parameterDefinition = row.parameterDefinition
  // 参数类型
  const parameterType = row.parameterType

  // 固定值类型专用校验
  if (row.processManner === '固定值') {
    const def = String(row.parameterDefinition || '').trim();
    const match = def.match(/^(-?\d+),(-?\d+)$/);
    if (match) {
      const min = Number(match[1]);
      const max = Number(match[2]);
      const val = Number(row.defaultValue);

      // 1) 必须是整数
      if (!Number.isInteger(val)) {
        ElMessage.warning(`参数“${row.parameterName}”必须是整数`);
        return false;
      }
      // 2) 必须在区间 [min,max]
      if (val < min || val > max) {
        ElMessage.warning(
            `参数“${row.parameterName}”必须为 ${min} 到 ${max} 之间的整数`
        );
        return false;
      }
    }
  }

  // 检查长度
/*  if (value && value.length !== parseInt(length)) {
    ElMessage.warning(`参数 "${row.parameterName}" 的长度必须为 ${length} 位`)
    return false
  }*/

  if(row.parameterType === '16进制' && value.startsWith('0x')) {
    value = value.replace('0x', '');
  }
  // 根据类型进行验证
  switch (row.parameterType) {
    case '布尔值':
      if (value && !['0', '1'].includes(value)) {
        ElMessage.warning(`布尔值参数只能为 0 或 1`)
        return false
      }
      break
    case '16进制':
      if (value && !/^[0-9A-Fa-f]+$/.test(value)) {
        ElMessage.warning(`16进制参数只能包含 0-9, A-F, a-f`)
        return false
      }
      break
    case '无符号类型':
    case '有符号类型':
      if (value && isNaN(value)) {
        ElMessage.warning(`数字参数必须为有效数字`)
        return false
      }
      break
      // 其他类型验证可以在这里添加
  }

  return true
}



// 保存参数
const saveParameters = async () => {
  // 验证所有参数
  for (const param of parameterList.value) {
    if (!validateValue(param)) {
      ElMessage.error(`参数 "${param.parameterName}" 的值不符合要求`)
      return
    }
  }


  if (!validateAllDefaultValue()) return // ⭐ 新增校验


    // 调用API保存参数
    const param = {
      instructionCode: props.instructionCode,
      satelliteId: props.satelliteId,
      instructionName: props.instructionName,
      selectedSatelliteCodes: props.selectedSatelliteCodes,
      zhunBeiFaSongZhiLingId: props.zhunBeiFaSongZhiLingId,
      satelliteIds: props.satelliteIds,
      parameters: parameterList.value,
      userId: userId,
      userName: userName,
      nickName: nickName,
    }
      await saveInstructionParametersSerive(param).then((response) => {
      console.log(response)
      if (response.code === 200) {
        ElMessage.success('参数保存成功' )

        const data = { foo: 'bar' }
        emit('saved', data) // 触发父组件方法
      } else {
        ElMessage.error('参数保存失败: ' + response.msg)
      }
    }).catch((error) => {
      ElMessage.error('参数保存失败: ' + error.message)
    })
}

// 关闭对话框
const handleClose = () => {
  ElMessageBox.confirm('确定要放弃已修改的参数值吗?', '提示', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning'
  }).then(() => {
    dialogVisible.value = false
  }).catch(() => {
    // 取消关闭
  })
}


/* ---- data ---- */
const saveAsVisible = ref(false)
const saveAsFormRef = ref()
const saveAsForm = reactive({
  instructionCode: '',
  instructionFlag: '',
  instructionName: '',
  comment: '',
})
const uniqueLoading = ref(false)
const isUnique = ref(false)
const uniqueMsg = ref('')

/* ---- 校验规则 ---- */
const saveAsRules = {
  instructionCode: [{ required: true, message: '请输入指令代码', trigger: 'blur' }],
  // instructionFlag: [{ required: true, message: '请输入指令标识', trigger: 'blur' }],
  instructionFlag: [
    { required: true, message: '请输入指令标识', trigger: 'blur' },
    {
      pattern: /^(0x)?[0-9a-fA-F]{4}$/,
      message: '必须是 2 字节 16 进制，例如 0xA1B2',
      trigger: 'blur'
    }
  ],
  instructionName: [{ required: true, message: '请输入指令名称', trigger: 'blur' }]
}

/* ---- 打开弹窗 ---- */
const openSaveAsDialog = () => {

  // 验证所有参数
  for (const param of parameterList.value) {
    if (!validateValue(param)) {
      ElMessage.error(`参数 "${param.parameterName}" 的值不符合要求`)
      return
    }
  }

  if (!validateAllDefaultValue()) return // ⭐ 新增校验


  saveAsVisible.value = true
  nextTick(() => saveAsFormRef.value?.resetFields())
  Object.assign(
      saveAsForm, {
        instructionCode: props.instructionCode,
        instructionFlag: instructionFlag.value,
        instructionName: props.instructionName,
        comment: ''
      })
  isUnique.value = false
  uniqueMsg.value = ''

}

/* ---- 实时唯一校验（防抖 500ms）---- */
const debounceCheck = debounce(() => checkUnique(), 500)

const checkUnique = async () => {
  if (!saveAsForm.instructionCode ||!saveAsForm.instructionFlag || !saveAsForm.instructionName) {
    isUnique.value = false
    uniqueMsg.value = ''
    return
  }
  uniqueLoading.value = true
  try {

    const params = {
      instructionCode: saveAsForm.instructionCode,
      instructionFlag: saveAsForm.instructionFlag,
      instructionName: saveAsForm.instructionName,

      satelliteIds:props.satelliteIds,
      satelliteCodes:props.selectedSatelliteCodes,
      zhunBeiFaSongZhiLingId: props.zhunBeiFaSongZhiLingId,
    }

    debounceCheckSerive(params).then((resp) => {
      console.log('resp~~~~~~~~~~~~~~~~~~~~~~~~~~',resp)
      if (resp.code === 200) {
        // uniqueMsg.value = data ? '✅ 可用' : '❌ 已存在'
        uniqueMsg.value = '✅ 可用'
        isUnique.value = true
      } else {
        // alert(resp.msg);
        // uniqueMsg.value = data ? '✅ 可用' : '❌ 已存在'
        // uniqueMsg.value = '❌ 已存在'+resp.msg
      }
    }).catch((error) => {
      isUnique.value = false
      // alert(JSON.stringify(error))
        uniqueMsg.value = '❌ 已存在'+error
    })
  } finally {
    uniqueLoading.value = false
  }
}

/* ---- 确认另存 ---- */
const confirmSaveAs = async () => {
  await saveAsFormRef.value.validate()
  const payload = {
    instructionCode: saveAsForm.instructionCode,
    instructionFlag: saveAsForm.instructionFlag,
    instructionName: saveAsForm.instructionName,
    comment: saveAsForm.comment,
    satelliteId: props.satelliteId,
    satelliteIds: props.satelliteIds,
    satelliteCodes:props.selectedSatelliteCodes,
    zhunBeiFaSongZhiLingId: props.zhunBeiFaSongZhiLingId,
    parameters: parameterList.value
  }
    confirmSaveAsSerive(payload).then(async (response) => {
      console.log('确认另存$$$$$$$$$$$$$$$$$$$$ ', response)
      if (response.code === 200) {
        ElMessage.success('另存成功！')
        // 回显最新指令参数
        await fetchParametersNew(saveAsForm.instructionCode)
        emit('saved')
        saveAsVisible.value = false
      } else {
        ElMessage.error(msg || '另存失败')
      }
    }).catch((error) => {
      ElMessage.error(e.message || '网络异常')
    })


}

/* ---- 拉取最新指令参数（回显）---- */
const fetchParametersNew = async (newCode) => {
  const { data } = await axios.get('/satellite/instruction/parameters', {
    params: { instructionCode: newCode }
  })
  parameterList.value = data || []
}

/**
 * 校验所有参数的 defaultValue 非空
 * @returns {boolean} true 通过 | false 不通过
 */
const validateAllDefaultValue = () => {
  // 只校验 parameterLength !== 0 的行
  const needCheck = parameterList.value.filter(
      p => Number(p.parameterLength) !== 0
  )
  const emptyParams = needCheck.filter(
      p => p.defaultValue === null || String(p.defaultValue).trim() === ''
  )

  if (emptyParams.length) {
    ElMessage.warning(
        `存在 ${emptyParams.length} 个参数未填写默认值：${emptyParams
            .map(p => p.parameterName)
            .join('、')}`
    )
    return false
  }
  return true
}
</script>

<style scoped>
.dialog-footer {
  display: flex;
  justify-content: flex-end;
}

.success { color: #67C23A; }
.error   { color: #F56C6C; }
/* 全局 */
.el-table .cell {
  white-space: normal;          /* 允许换行 */
  overflow: hidden;             /* 超出隐藏 */
  text-overflow: ellipsis;      /* 省略号 */
  display: -webkit-box;         /* 弹性盒模型 */
  -webkit-line-clamp: 2;        /* 最多两行，可自行调整 */
  -webkit-box-orient: vertical;
}

/* 如果写在 scoped 里 */
::v-deep(.el-table .cell) {
  white-space: normal;
  overflow: hidden;
  text-overflow: ellipsis;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
}
</style>
